home *** CD-ROM | disk | FTP | other *** search
/ Aminet 16 / Aminet 16 (1996)(GTI - Schatztruhe)[!][Dec 1996].iso / Aminet / comm / term / term_source.lha / Extras / Source / term-source.lha / Marker.c < prev    next >
C/C++ Source or Header  |  1996-10-20  |  18KB  |  820 lines

  1. /*
  2. **    Marker.c
  3. **
  4. **    Text block marker routines
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9. **    :ts=4
  10. */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "Global.h"
  14. #endif
  15.  
  16.     /* BM_Draw():
  17.      *
  18.      *    Redraw or remove marked regions.
  19.      */
  20.  
  21. VOID
  22. BM_Draw(struct BlockMarker *Marker)
  23. {
  24.         /* Is the first line the same as the last line? If so,
  25.          * continue and mark only single characters. Else,
  26.          * determine first line and column to mark and last
  27.          * line and last column.
  28.          */
  29.  
  30.     if(Marker->FirstLine != Marker->LastLine)
  31.     {
  32.         LONG    First    = Marker->FirstLine - Marker->Top,
  33.                 Last    = Marker->LastLine  - Marker->Top,
  34.                 Lines;
  35.  
  36.             /* Is the first line visible? If so, mark it. */
  37.  
  38.         if(First >= 0)
  39.             ToggleSelect(Marker,Marker->FirstColumn,First,Marker->Width - Marker->FirstColumn,1);
  40.         else
  41.         {
  42.             ToggleSelect(Marker,0,0,Marker->Width,1);
  43.  
  44.             First = 0;
  45.         }
  46.  
  47.             /* Is the last line visible? If so, mark it. */
  48.  
  49.         if(Last >= 0 && Last < Marker->Height)
  50.             ToggleSelect(Marker,0,Last,Marker->LastColumn,1);
  51.         else
  52.             Last = Marker->Height;
  53.  
  54.             /* Determine the number of lines the selection spans. */
  55.  
  56.         if((Lines = Last - First - 1) > 0)
  57.             ToggleSelect(Marker,0,First + 1,Marker->Width,Lines);
  58.     }
  59.     else
  60.     {
  61.             /* Is the first column different from the last column? */
  62.  
  63.         if(Marker->FirstColumn != Marker->LastColumn)
  64.         {
  65.                 /* Is the line visible? If so, mark it. */
  66.  
  67.             if(Marker->Top <= Marker->LastLine && Marker->LastLine < Marker->Top + Marker->Height)
  68.                 ToggleSelect(Marker,Marker->FirstColumn,Marker->FirstLine - Marker->Top,Marker->LastColumn - Marker->FirstColumn,1);
  69.         }
  70.     }
  71. }
  72.  
  73.     /* BM_ClearMark(struct BlockMarker *Marker):
  74.      *
  75.      *    Free block marker memory.
  76.      */
  77.  
  78. VOID
  79. BM_ClearMark(struct BlockMarker *Marker)
  80. {
  81.     BM_Draw(Marker);
  82.  
  83.     FreeVecPooled(Marker);
  84. }
  85.  
  86.     /* BM_SetMark():
  87.      *
  88.      *    Create block marker structure.
  89.      */
  90.  
  91. struct BlockMarker *
  92. BM_SetMark(struct RastPort *RPort,LONG Width,LONG Height,LONG LeftEdge,LONG TopEdge,LONG Top,LONG Lines,LONG X,LONG Y,LONG TextFontWidth,LONG TextFontHeight)
  93. {
  94.     if(Height && Lines)
  95.     {
  96.         struct BlockMarker *Marker;
  97.  
  98.             /* Allocate marker buffer. */
  99.  
  100.         if(Marker = (struct BlockMarker *)AllocVecPooled(sizeof(struct BlockMarker),MEMF_ANY | MEMF_CLEAR))
  101.         {
  102.                 /* Fill in the RastPort. */
  103.  
  104.             Marker->RPort = RPort;
  105.  
  106.                 /* Fill in the canvas left and top edge. */
  107.  
  108.             Marker->LeftEdge    = LeftEdge;
  109.             Marker->TopEdge        = TopEdge;
  110.  
  111.                 /* Fill in current display window top and number of
  112.                  * lines in the buffer.
  113.                  */
  114.  
  115.             Marker->Top        = Top;
  116.             Marker->Lines    = Lines;
  117.  
  118.                 /* Fill in width and height of the display window. */
  119.  
  120.             Marker->Width    = Width;
  121.             Marker->Height    = Height;
  122.  
  123.                 /* Fill in the marker anchor point. */
  124.  
  125.             Marker->FirstColumn    = X;
  126.             Marker->LastColumn    = X;
  127.             Marker->FirstLine    = Y + Top;
  128.             Marker->LastLine    = Y + Top;
  129.  
  130.                 /* Fill in current mouse position. */
  131.  
  132.             Marker->LastX    = X;
  133.             Marker->LastY    = Y;
  134.  
  135.             Marker->OriginX    = X;
  136.             Marker->OriginY    = Y + Top;
  137.  
  138.                 /* Remember text font dimensions. */
  139.  
  140.             Marker->TextFontWidth    = TextFontWidth;
  141.             Marker->TextFontHeight    = TextFontHeight;
  142.  
  143.             Marker->WriteMask = RPort->Mask;
  144.         }
  145.  
  146.             /* Return marker buffer. */
  147.  
  148.         return(Marker);
  149.     }
  150.     else
  151.         return(NULL);
  152. }
  153.  
  154.     /* BM_ExtendMark(struct BlockMarker *Marker,LONG X,LONG Y,LONG Delta):
  155.      *
  156.      *    Extend current block marker. This routine was
  157.      *    first written by me, but Martin Berndt rewrote it
  158.      *    after we both realised that it would not work
  159.      *    properly.
  160.      */
  161.  
  162. VOID
  163. BM_ExtendMark(struct BlockMarker *Marker,LONG X,LONG Y,LONG Delta)
  164. {
  165.     if(Marker->LastX != X || Marker->LastY != Y)
  166.     {
  167.         LONG    OldCharPos,NewCharPos,
  168.                 CharStart,CharEnd,
  169.                 CharOrigin,
  170.                 OriginY,
  171.                 Lines;
  172.         BOOL    Crossed;
  173.  
  174.         OriginY = Marker->OriginY - Marker->Top;
  175.  
  176.             /* Deal with illegal X position. */
  177.  
  178.         if(X < 0)
  179.             X = 0;
  180.  
  181.         if(X > Marker->Width)
  182.             X = Marker->Width;
  183.  
  184.             /* Deal with illegal Y position. */
  185.  
  186.         if(Y < 0)
  187.             Y = 0;
  188.  
  189.         if(Y >= Marker->Height)
  190.             Y = Marker->Height - 1;
  191.  
  192.         if(Y + Marker->Top >= Marker->Lines)
  193.             Y = Marker->Lines - Marker->Top - 1;
  194.  
  195.             /* Is the Y position larger than the last line? If so,
  196.              * truncate it.
  197.              */
  198.  
  199.         if(Y > Marker->Lines - Marker->Top)
  200.             Y -= Marker->Lines - Marker->Top;
  201.  
  202.             /* Select the text. */
  203.  
  204.         OldCharPos    = (Marker->LastY + Marker->Top) * Marker->Width + Marker->LastX;
  205.         NewCharPos    = (Y + Marker->Top) * Marker->Width + X;
  206.  
  207.         CharStart    = Marker->FirstLine * Marker->Width + Marker->FirstColumn;
  208.         CharEnd        = Marker->LastLine * Marker->Width + Marker->LastColumn;
  209.  
  210.         CharOrigin    = Marker->OriginY * Marker->Width + Marker->OriginX;
  211.  
  212.         Crossed        = (OldCharPos < CharOrigin) ^ (NewCharPos < CharOrigin);
  213.  
  214.         if(NewCharPos > OldCharPos)
  215.         {
  216.             if(Delta && Y < OriginY)
  217.                 ToggleSelect(Marker,0,Y,Marker->Width,1);
  218.  
  219.             if(Crossed)
  220.             {
  221.                 if((Lines = OriginY - Marker->LastY - 1) >= 0)
  222.                 {
  223.                     ToggleSelect(Marker,Marker->LastX,Marker->LastY,Marker->Width - Marker->LastX,1);
  224.  
  225.                     if(Lines > 0)
  226.                         ToggleSelect(Marker,0,Marker->LastY + 1,Marker->Width,Lines);
  227.  
  228.                     if(Marker->OriginX)
  229.                         ToggleSelect(Marker,0,OriginY,Marker->OriginX,1);
  230.                 }
  231.                 else
  232.                 {
  233.                     if(Delta)
  234.                         ToggleSelect(Marker,0,OriginY,Marker->LastX,1);
  235.                     else
  236.                         ToggleSelect(Marker,Marker->LastX,OriginY,Marker->OriginX - Marker->LastX,1);
  237.                 }
  238.  
  239.                 Marker->FirstColumn    = Marker->OriginX;
  240.                 Marker->FirstLine     = Marker->OriginY;
  241.  
  242.                 Marker->LastX        = Marker->OriginX;
  243.                 Marker->LastY        = OriginY;
  244.             }
  245.             else
  246.             {
  247.                 if(OldCharPos < CharOrigin)
  248.                 {
  249.                     if((Lines = Y - Marker->LastY - 1) >= 0)
  250.                     {
  251.                         ToggleSelect(Marker,Marker->LastX,Marker->LastY,Marker->Width - Marker->LastX,1);
  252.  
  253.                         if(Lines > 0)
  254.                             ToggleSelect(Marker,0,Marker->LastY + 1,Marker->Width,Lines);
  255.  
  256.                         ToggleSelect(Marker,0,Y,X,1);
  257.                     }
  258.                     else
  259.                     {
  260.                         if(Delta)
  261.                             ToggleSelect(Marker,0,Y,X,1);
  262.                         else
  263.                             ToggleSelect(Marker,Marker->LastX,Y,X - Marker->LastX,1);
  264.                     }
  265.  
  266.                     Marker->FirstColumn    = X;
  267.                     Marker->FirstLine    = Y + Marker->Top;
  268.                 }
  269.             }
  270.  
  271.             if(NewCharPos > CharEnd)
  272.             {
  273.                 if((Lines = Y - Marker->LastY - 1) >= 0)
  274.                 {
  275.                     ToggleSelect(Marker,Marker->LastX,Marker->LastY,Marker->Width - Marker->LastX,1);
  276.  
  277.                     if(Lines > 0)
  278.                         ToggleSelect(Marker,0,Marker->LastY + 1,Marker->Width,Lines);
  279.  
  280.                     ToggleSelect(Marker,0,Y,X,1);
  281.                 }
  282.                 else
  283.                 {
  284.                     if(Delta)
  285.                         ToggleSelect(Marker,0,Y,X,1);
  286.                     else
  287.                         ToggleSelect(Marker,Marker->LastX,Y,X - Marker->LastX,1);
  288.                 }
  289.  
  290.                 Marker->LastColumn    = X;
  291.                 Marker->LastLine    = Y + Marker->Top;
  292.             }
  293.         }
  294.         else
  295.         {
  296.             if(Delta && Y > OriginY)
  297.                 ToggleSelect(Marker,0,Y,Marker->Width,1);
  298.  
  299.             if(Crossed)
  300.             {
  301.                 if((Lines = Marker->LastY - OriginY - 1) >= 0)
  302.                 {
  303.                     ToggleSelect(Marker,0,Marker->LastY,Marker->LastX,1);
  304.  
  305.                     if(Lines > 0)
  306.                         ToggleSelect(Marker,0,OriginY + 1,Marker->Width,Lines);
  307.  
  308.                     ToggleSelect(Marker,Marker->OriginX,OriginY,Marker->Width - Marker->OriginX,1);
  309.                 }
  310.                 else
  311.                 {
  312.                     if(Delta)
  313.                         ToggleSelect(Marker,Marker->LastX,OriginY,Marker->Width - Marker->LastX,1);
  314.                     else
  315.                         ToggleSelect(Marker,Marker->OriginX,OriginY,Marker->LastX - Marker->OriginX,1);
  316.                 }
  317.  
  318.                 Marker->LastColumn    = Marker->OriginX;
  319.                 Marker->LastLine    = Marker->OriginY;
  320.  
  321.                 Marker->LastX        = Marker->OriginX;
  322.                 Marker->LastY        = OriginY;
  323.             }
  324.             else
  325.             {
  326.                 if(OldCharPos > CharOrigin)
  327.                 {
  328.                     if((Lines = Marker->LastY - Y - 1) >= 0)
  329.                     {
  330.                         if(Marker->LastX)
  331.                             ToggleSelect(Marker,0,Marker->LastY,Marker->LastX,1);
  332.  
  333.                         if(Lines > 0)
  334.                             ToggleSelect(Marker,0,Y + 1,Marker->Width,Lines);
  335.  
  336.                         ToggleSelect(Marker,X,Y,Marker->Width - X,1);
  337.                     }
  338.                     else
  339.                     {
  340.                         if(Delta)
  341.                             ToggleSelect(Marker,X,Y,Marker->Width - X,1);
  342.                         else
  343.                             ToggleSelect(Marker,X,Y,Marker->LastX - X,1);
  344.                     }
  345.  
  346.                     Marker->LastColumn    = X;
  347.                     Marker->LastLine    = Y + Marker->Top;
  348.                 }
  349.             }
  350.  
  351.             if(NewCharPos < CharStart)
  352.             {
  353.                 if((Lines = Marker->LastY - Y - 1) >= 0)
  354.                 {
  355.                     if(Marker->LastX)
  356.                         ToggleSelect(Marker,0,Marker->LastY,Marker->LastX,1);
  357.  
  358.                     if(Lines > 0)
  359.                         ToggleSelect(Marker,0,Y + 1,Marker->Width,Lines);
  360.  
  361.                     ToggleSelect(Marker,X,Y,Marker->Width - X,1);
  362.                 }
  363.                 else
  364.                 {
  365.                     if(Delta)
  366.                         ToggleSelect(Marker,X,Y,Marker->Width - X,1);
  367.                     else
  368.                         ToggleSelect(Marker,X,Y,Marker->LastX - X,1);
  369.                 }
  370.  
  371.                 Marker->FirstColumn    = X;
  372.                 Marker->FirstLine    = Y + Marker->Top;
  373.             }
  374.         }
  375.  
  376.         Marker->LastX = X;
  377.         Marker->LastY = Y;
  378.     }
  379. }
  380.  
  381.  
  382.     /* ToggleSelect(struct BlockMarker *Marker,LONG Left,LONG Top,LONG Width,LONG Height):
  383.      *
  384.      *    Toggle selection subroutine.
  385.      */
  386.  
  387. VOID
  388. ToggleSelect(struct BlockMarker *Marker,LONG Left,LONG Top,LONG Width,LONG Height)
  389. {
  390.     if(Width && Height)
  391.     {
  392.         struct RastPort *RPort = Marker->RPort;
  393.  
  394.         ULONG    OldAPen    = ReadAPen(RPort),
  395.                 OldBPen    = ReadBPen(RPort),
  396.                 OldDrMd    = ReadDrMd(RPort),
  397.                 Mask;
  398.  
  399.         Left    = Marker->LeftEdge + Left * Marker->TextFontWidth;
  400.         Top        = Marker->TopEdge + Top * Marker->TextFontHeight;
  401.  
  402.         if(Kick30)
  403.             Mask = (1L << GetBitMapAttr(RPort->BitMap,BMA_DEPTH)) - 1;
  404.         else
  405.             Mask = (1L << RPort->BitMap->Depth) - 1;
  406.  
  407.         SetPens(RPort,Mask,OldBPen,JAM1 | COMPLEMENT);
  408.  
  409.         FillBox(RPort,Left,Top,Width * Marker->TextFontWidth,Height * Marker->TextFontHeight);
  410.  
  411.         SetPens(RPort,OldAPen,OldBPen,OldDrMd);
  412.     }
  413. }
  414.  
  415.     /* WriteTrimmedString(struct IFFHandle *Handle,STRPTR String,LONG Len,BOOL NeedClipConversion):
  416.      *
  417.      *    Write a string to the clipboard, sans trailing spaces.
  418.      */
  419.  
  420. VOID
  421. WriteTrimmedString(struct IFFHandle *Handle,STRPTR String,LONG Len,BOOL NeedClipConversion)
  422. {
  423.     while(Len > 0 && String[Len - 1] == ' ')
  424.         Len--;
  425.  
  426.     if(Len)
  427.     {
  428.         if(NeedClipConversion)
  429.         {
  430.             UBYTE    Buffer[256];
  431.             LONG    Size,i;
  432.             STRPTR    Dest;
  433.             UBYTE    c;
  434.  
  435.             do
  436.             {
  437.                 Size = MIN(Len,sizeof(Buffer));
  438.  
  439.                 Len -= Size;
  440.  
  441.                 for(i = 0, Dest = Buffer ; i < Size ; i++)
  442.                 {
  443.                     if(c = ISOConversion[*String++])
  444.                         *Dest++ = c;
  445.                     else
  446.                         *Dest++ = ' ';
  447.                 }
  448.  
  449.                 if(Dest > Buffer)
  450.                 {
  451.                     Size = (ULONG)Dest - (ULONG)&Buffer[0];
  452.  
  453.                     while(Size > 0 && Buffer[Size - 1] == ' ')
  454.                         Size--;
  455.  
  456.                     if(Size > 0)
  457.                         WriteChunkBytes(Handle,Buffer,Size);
  458.                 }
  459.             }
  460.             while(Len > 0);
  461.         }
  462.         else
  463.             WriteChunkBytes(Handle,String,Len);
  464.     }
  465. }
  466.  
  467.     /* ClipPage(struct BlockMarker *Marker,BOOL Append,BOOL NeedClipConversion):
  468.      *
  469.      *    Send the entire marked page to the clipboard.
  470.      */
  471.  
  472. STATIC VOID
  473. ClipPage(struct BlockMarker *Marker,BOOL Append,BOOL NeedClipConversion)
  474. {
  475.     struct IFFHandle *Handle;
  476.     APTR Buffer;
  477.     LONG Size;
  478.  
  479.     if(Append)
  480.         GetClipContents(Config->ClipConfig->ClipboardUnit,&Buffer,&Size);
  481.     else
  482.     {
  483.         Buffer    = NULL;
  484.         Size    = 0;
  485.     }
  486.  
  487.     if(Handle = OpenIFFClip(Config->ClipConfig->ClipboardUnit,MODE_NEWFILE))
  488.     {
  489.         if(!PushChunk(Handle,ID_FTXT,ID_FORM,IFFSIZE_UNKNOWN))
  490.         {
  491.             if(!PushChunk(Handle,0,ID_CHRS,IFFSIZE_UNKNOWN))
  492.             {
  493.                 LONG i,Lines = Marker->LastLine - Marker->FirstLine - 1;
  494.  
  495.                 if(Buffer)
  496.                 {
  497.                     WriteChunkBytes(Handle,Buffer,Size);
  498.  
  499.                     FreeVecPooled(Buffer);
  500.                 }
  501.  
  502.                 WriteTrimmedString(Handle,&Raster[RasterWidth * Marker->FirstLine + Marker->FirstColumn],Marker->Width - Marker->FirstColumn,NeedClipConversion);
  503.                 WriteChunkBytes(Handle,"\n",1);
  504.  
  505.                 if(Lines > 0)
  506.                 {
  507.                     STRPTR Line = &Raster[(Marker->FirstLine + 1) * RasterWidth];
  508.  
  509.                     for(i = 0 ; i < Lines ; i++)
  510.                     {
  511.                         WriteTrimmedString(Handle,Line,Marker->Width,NeedClipConversion);
  512.                         WriteChunkBytes(Handle,"\n",1);
  513.  
  514.                         Line += RasterWidth;
  515.                     }
  516.                 }
  517.  
  518.                 WriteTrimmedString(Handle,&Raster[RasterWidth * Marker->LastLine],Marker->LastColumn,NeedClipConversion);
  519.                 WriteChunkBytes(Handle,"\n",1);
  520.  
  521.                 PopChunk(Handle);
  522.             }
  523.  
  524.             PopChunk(Handle);
  525.         }
  526.  
  527.         CloseIFFClip(Handle);
  528.     }
  529. }
  530.  
  531.     /* MarkWord(LONG MouseX,LONG MouseY):
  532.      *
  533.      *    Mark a single word on the main screen (double-click).
  534.      */
  535.  
  536. VOID
  537. MarkWord(LONG MouseX,LONG MouseY)
  538. {
  539.     LONG FirstX,FirstY;
  540.  
  541.     FirstX = (MouseX * CharCellDenominator) / (TextFontWidth * CharCellNominator);
  542.     FirstY = MouseY / TextFontHeight;
  543.  
  544.     if(FirstX > LastPrintableColumn)
  545.         FirstX = LastPrintableColumn;
  546.  
  547.     if(FirstY > LastLine)
  548.         FirstY = LastLine;
  549.  
  550.     SafeObtainSemaphoreShared(&RasterSemaphore);
  551.  
  552.     if(Raster[FirstY * RasterWidth + FirstX] != ' ' && Raster[FirstY * RasterWidth + FirstX])
  553.     {
  554.         STRPTR    Line = &Raster[FirstY * RasterWidth];
  555.         LONG    LastX;
  556.  
  557.         LastX = FirstX;
  558.  
  559.         while(FirstX > 0 && Line[FirstX - 1] != ' ')
  560.             FirstX--;
  561.  
  562.         while(LastX < LastPrintableColumn && Line[LastX + 1] != ' ')
  563.             LastX++;
  564.  
  565.         ObtainSemaphore(&TerminalSemaphore);
  566.  
  567.         if(WindowMarker = BM_SetMark(Window->RPort,LastPrintableColumn + 1,LastLine + 1,WindowLeft,WindowTop,0,LastLine + 1,FirstX,FirstY,(TextFontWidth * CharCellNominator) / CharCellDenominator,TextFontHeight))
  568.         {
  569.             SetMask(RPort,DepthMask);
  570.  
  571.             Marking = TRUE;
  572.  
  573.             ReportMouse(TRUE,Window);
  574.  
  575.             BM_ExtendMark(WindowMarker,LastX + 1,FirstY,0);
  576.  
  577.             SetClipMenu(TRUE);
  578.         }
  579.  
  580.         ReleaseSemaphore(&TerminalSemaphore);
  581.     }
  582.  
  583.     ReleaseSemaphore(&RasterSemaphore);
  584. }
  585.  
  586.     /* SetMarker(LONG MouseX,LONG MouseY):
  587.      *
  588.      *    Anchor a marker to the current mouse position.
  589.      */
  590.  
  591. VOID
  592. SetMarker(LONG MouseX,LONG MouseY)
  593. {
  594.     LONG FirstX,FirstY;
  595.  
  596.     FirstX = (MouseX * CharCellDenominator) / (TextFontWidth * CharCellNominator);
  597.     FirstY = MouseY / TextFontHeight;
  598.  
  599.     if(FirstX > LastPrintableColumn)
  600.         FirstX = LastPrintableColumn;
  601.  
  602.     if(FirstY > LastLine)
  603.         FirstY = LastLine;
  604.  
  605.     ObtainSemaphore(&TerminalSemaphore);
  606.  
  607.     if(WindowMarker = BM_SetMark(Window->RPort,LastPrintableColumn + 1,LastLine + 1,WindowLeft,WindowTop,0,LastLine + 1,FirstX,FirstY,(TextFontWidth * CharCellNominator) / CharCellDenominator,TextFontHeight))
  608.     {
  609.         SetMask(RPort,DepthMask);
  610.  
  611.         Marking = TRUE;
  612.  
  613.         ReportMouse(TRUE,Window);
  614.  
  615.         SetClipMenu(TRUE);
  616.     }
  617.  
  618.     ReleaseSemaphore(&TerminalSemaphore);
  619. }
  620.  
  621.     /* MoveMarker(LONG MouseX,LONG MouseY):
  622.      *
  623.      *    Move the marker with the mouse.
  624.      */
  625.  
  626. VOID
  627. MoveMarker(LONG MouseX,LONG MouseY)
  628. {
  629.     if(WindowMarker)
  630.     {
  631.         ULONG EffectiveWidth;
  632.  
  633.         ObtainSemaphore(&TerminalSemaphore);
  634.  
  635.         EffectiveWidth = (TextFontWidth * CharCellNominator) / CharCellDenominator;
  636.  
  637.         BM_ExtendMark(WindowMarker,(MouseX + EffectiveWidth - 1) / EffectiveWidth,MouseY / TextFontHeight,0);
  638.  
  639.         ReleaseSemaphore(&TerminalSemaphore);
  640.     }
  641. }
  642.  
  643.     /* DropMarker():
  644.      *
  645.      *    Drop the window marker, restore the window contents.
  646.      */
  647.  
  648. VOID
  649. DropMarker()
  650. {
  651.     if(WindowMarker)
  652.     {
  653.         struct RastPort    *RPort = WindowMarker->RPort;
  654.         LONG Mask = WindowMarker->WriteMask;
  655.  
  656.         ObtainSemaphore(&TerminalSemaphore);
  657.  
  658.         BM_ClearMark(WindowMarker);
  659.  
  660.         ReleaseSemaphore(&TerminalSemaphore);
  661.  
  662.         SetMask(RPort,Mask);
  663.  
  664.         ReportMouse(FALSE,Window);
  665.  
  666.         WindowMarker = NULL;
  667.  
  668.         Marking = FALSE;
  669.  
  670.         SetClipMenu(FALSE);
  671.     }
  672. }
  673.  
  674.     /* FreeMarker():
  675.      *
  676.      *    Free the main window marker.
  677.      */
  678.  
  679. VOID
  680. FreeMarker()
  681. {
  682.     if(WindowMarker)
  683.     {
  684.         struct RastPort    *RPort = WindowMarker->RPort;
  685.         LONG Mask = WindowMarker->WriteMask;
  686.  
  687.         FreeVecPooled(WindowMarker);
  688.  
  689.         WindowMarker = NULL;
  690.  
  691.         SetMask(RPort,Mask);
  692.  
  693.         ReportMouse(FALSE,Window);
  694.  
  695.         Marking = FALSE;
  696.  
  697.         SetClipMenu(FALSE);
  698.     }
  699. }
  700.  
  701.     /* ClipMarker(BOOL Append):
  702.      *
  703.      *    Transfer the marked area to the clipboard.
  704.      */
  705.  
  706. VOID
  707. ClipMarker(BOOL Append)
  708. {
  709.     if(WindowMarker)
  710.     {
  711.         SafeObtainSemaphoreShared(&RasterSemaphore);
  712.  
  713.         SetWait(Window);
  714.  
  715.         if(WindowMarker->FirstColumn == WindowMarker->Width)
  716.         {
  717.             WindowMarker->FirstLine++;
  718.  
  719.             WindowMarker->FirstColumn = 0;
  720.         }
  721.  
  722.         if(WindowMarker->LastColumn == 0)
  723.         {
  724.             WindowMarker->LastLine--;
  725.  
  726.             WindowMarker->LastColumn = WindowMarker->Width;
  727.         }
  728.  
  729.         if(WindowMarker->FirstLine <= WindowMarker->LastLine)
  730.         {
  731.             if(WindowMarker->FirstLine != WindowMarker->LastLine || WindowMarker->FirstColumn != WindowMarker->LastColumn)
  732.             {
  733.                 if(WindowMarker->FirstLine == WindowMarker->LastLine)
  734.                 {
  735.                     if(Config->TerminalConfig->FontMode != FONT_STANDARD)
  736.                     {
  737.                         UBYTE    Buffer[256];
  738.                         LONG    Len,i;
  739.                         STRPTR    Dest,Source;
  740.                         LONG    Size;
  741.                         LONG    c;
  742.  
  743.                         Source = &Raster[RasterWidth * WindowMarker->FirstLine + WindowMarker->FirstColumn];
  744.                         Size = WindowMarker->LastColumn - WindowMarker->FirstColumn;
  745.  
  746.                         if(Append)
  747.                         {
  748.                             do
  749.                             {
  750.                                 Len = MIN(Size,sizeof(Buffer));
  751.  
  752.                                 Size -= Len;
  753.  
  754.                                 for(i = 0, Dest = Buffer ; i < Len ; i++)
  755.                                 {
  756.                                     if(c = ISOConversion[*Source++])
  757.                                         *Dest++ = c;
  758.                                     else
  759.                                         *Dest++ = ' ';
  760.                                 }
  761.  
  762.                                 if(Dest > Buffer)
  763.                                     AddClip(Buffer,(ULONG)Dest - (ULONG)&Buffer[0]);
  764.                             }
  765.                             while(Size > 0);
  766.                         }
  767.                         else
  768.                         {
  769.                             BOOL FirstWrite = TRUE;
  770.  
  771.                             do
  772.                             {
  773.                                 Len = MIN(Size,sizeof(Buffer));
  774.  
  775.                                 Size -= Len;
  776.  
  777.                                 for(i = 0, Dest = Buffer ; i < Len ; i++)
  778.                                 {
  779.                                     if(c = ISOConversion[*Source++])
  780.                                         *Dest++ = c;
  781.                                     else
  782.                                         *Dest++ = ' ';
  783.                                 }
  784.  
  785.                                 if(Dest > Buffer)
  786.                                 {
  787.                                     if(FirstWrite)
  788.                                     {
  789.                                         FirstWrite = FALSE;
  790.  
  791.                                         SaveClip(Buffer,(ULONG)Dest - (ULONG)&Buffer[0]);
  792.                                     }
  793.                                     else
  794.                                         AddClip(Buffer,(ULONG)Dest - (ULONG)&Buffer[0]);
  795.                                 }
  796.                             }
  797.                             while(Size > 0);
  798.                         }
  799.                     }
  800.                     else
  801.                     {
  802.                         if(Append)
  803.                             AddClip(&Raster[RasterWidth * WindowMarker->FirstLine + WindowMarker->FirstColumn],WindowMarker->LastColumn - WindowMarker->FirstColumn);
  804.                         else
  805.                             SaveClip(&Raster[RasterWidth * WindowMarker->FirstLine + WindowMarker->FirstColumn],WindowMarker->LastColumn - WindowMarker->FirstColumn);
  806.                     }
  807.                 }
  808.                 else
  809.                     ClipPage(WindowMarker,Append,Config->TerminalConfig->FontMode != FONT_STANDARD);
  810.             }
  811.         }
  812.  
  813.         ClrWait(Window);
  814.  
  815.         ReleaseSemaphore(&RasterSemaphore);
  816.  
  817.         DropMarker();
  818.     }
  819. }
  820.